﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Psl.Applications;
using Psl.Controls;

namespace Stl.Controls
{
    /// <summary>
    /// Control qui contient la liste des composants de la palette.
    /// </summary>
    public partial class DesignToolbox : UserControl
    {
        /// <summary>
        /// Constructeur.
        /// </summary>
        public DesignToolbox()
        {
            InitializeComponent();
            InitViewComboBox();
            InitContextMenu();
            InitList();
        }

        /// <summary>
        /// Initialisation de la ComboBox contenant liste des styles.
        /// </summary>
        private void InitViewComboBox()
        {
            Type viewType = listView.View.GetType();
            string[] names = Enum.GetNames(viewType);
            viewComboBox.Items.AddRange(names);
            viewComboBox.SelectedIndex = (int)listView.View;
        }

        /// <summary>
        /// Initialisation du menu contextuel pour changer de style.
        /// </summary>
        private void InitContextMenu()
        {
            Type viewType = listView.View.GetType();
            string[] names = Enum.GetNames(viewType);
            foreach (string name in names)
            {
                //ToolStripDropDownItem
                ToolStripItem item = viewToolStripMenuItem.DropDownItems.Add(name);
                item.Click += toolStripItem_Clicked;
            }
        }

        /// <summary>
        /// Ajout des différents composants.
        /// </summary>
        private void InitList()
        {
            this.RegisterControl(typeof(Label));
            this.RegisterControl(typeof(ComboBoxEnh));
            this.RegisterControl(typeof(ComboBoxIndex));
            this.RegisterControl(typeof(Button));
            this.RegisterControl(typeof(CheckBox));
            this.RegisterControl(typeof(ListView));
            this.RegisterControl(typeof(TextBox));
            this.RegisterControl(typeof(ComboBox));
        }

        /// <summary>
        /// Evènement associé au clic du menu contectuel.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripItem_Clicked(Object sender, EventArgs e)
        {
            listView.View = (View)viewToolStripMenuItem.DropDownItems.IndexOf((ToolStripItem)sender);
        }

        /// <summary>
        /// Evènement associé au changement de style de la liste.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void viewComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            listView.View = (View)viewComboBox.SelectedIndex;
        }

        /// <summary>
        /// Action associée au clic du bouton de déselection de tous les composants.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void deselectButton_Click(object sender, EventArgs e)
        {
            UnSelectAll();
        }

        /// <summary>
        /// Classe pour représenter un control.
        /// </summary>
        public class ControlData
        {
            /// <summary>
            /// Type du composant.
            /// </summary>
            public Type Type { get; private set; }

            /// <summary>
            /// Curseur correspodant au compoosant.
            /// </summary>
            public Cursor Cursor { get; private set; }

            /// <summary>
            /// Constructeur.
            /// </summary>
            /// <param name="type"></param>
            /// <param name="cursor"></param>
            public ControlData(Type type, Cursor cursor)
            {
                this.Type = type;
                this.Cursor = cursor;
            }           
        }

        /// <summary>
        /// Permet d'ajouter un composant à la palette.
        /// </summary>
        /// <param name="type"></param>
        public void RegisterControl(Type type)
        {
            if (type == null)
                throw new ArgumentNullException();
            if (!type.IsSubclassOf(typeof(Control)))
                throw new ArgumentException();

            Cursor cursor;
            Image largeImage, smallImage;

            if (CursorHelper.GetComponentImages(type, out smallImage, out largeImage, out cursor))
            {
                smallImageList.Images.Add(type.FullName, smallImage);
                largeImageList.Images.Add(type.FullName, largeImage);
            }
            ListViewItem item = listView.Items.Add(new ListViewItem(type.Name, type.FullName));
            item.Tag = new ControlData(type, cursor);
        }

        /// <summary>
        /// Permet de désélectionner tous les composants.
        /// </summary>
        public void UnSelectAll()
        {
            listView.SelectedItems.Clear();
        }

        /// <summary>
        /// Retourne le contrôle séléctionné.
        /// </summary>
        public ControlData SelectedControl {
            get
            {
                ListView.SelectedListViewItemCollection items = listView.SelectedItems;
                if (items.Count == 0)
                    return null;
                else
                    return (ControlData)items[0].Tag;
            }
        }

        /// <summary>
        /// Evènement pour gérer le changement du composant séléctionné.
        /// </summary>
        public event EventHandler SelectedControlChanged;

        /// <summary>
        /// Appelé lorsque la séléction du composant à changé.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnSelectedControlChanged(Object sender, EventArgs e)
        {
            if (SelectedControlChanged != null)
                SelectedControlChanged(this, e);
        }

        /// <summary>
        /// Déclenché lorsque la séléction de la liste change.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listView_SelectedIndexChanged(Object sender, EventArgs e)
        {
            OnSelectedControlChanged(this, e);
        }

        /// <summary>
        /// Evènement déclénché lors du drag and drop.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listView_ItemDrag(object sender, ItemDragEventArgs e)
        {
            ListView list = sender as ListView;
            list.DoDragDrop(this.SelectedControl, DragDropEffects.Move);
        }
    }
}
